package com.lcc.lynx.jdbc;

import com.lcc.lynx.common.utils.AssertUtil;
import com.lcc.lynx.common.utils.ReflectUtil;
import com.lcc.lynx.common.utils.StrUtil;
import com.lcc.lynx.jdbc.pojo.TablePojo;
import com.lcc.lynx.jdbc.util.JDBCReflectUtil;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.List;

/**
 * service根据id操作
 *
 * @param <DV>
 */
public interface IByIdService<DV extends TablePojo> extends IBaseService<DV> {

    /**
     * 根据id查询
     *
     * @param id
     * @return
     * @author lcc
     * @date 2024/12/30 13:49
     */
    default DV selectById(String id) {
        AssertUtil.isFalse(StrUtil.isEmpty(id), "参数(id)不能为空");
        List<DV> list = getMapper().select(JDBCReflectUtil.getDVAndSetId(this.getClass(), id));
        return list.isEmpty() ? null : list.get(0);
    }

    /**
     * 根据id查询
     *
     * @param id
     * @return
     * @author lcc
     * @date 2024/12/30 13:49
     */
    default <T extends Number> DV selectById(T id) {
        AssertUtil.isFalse(StrUtil.isEmpty(id), "参数(id)不能为空");
        List<DV> list = getMapper().select(JDBCReflectUtil.getDVAndSetId(this.getClass(), id));
        return list.isEmpty() ? null : list.get(0);
    }

    /**
     * 更新一个
     *
     * @param dv 含有id的实体类
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    default int updateById(DV dv) {
        Field field = JDBCReflectUtil.getTableIdField(dv);
        Serializable fieldValue = (Serializable) ReflectUtil.getFieldValue(dv, field);
        AssertUtil.isFalse(StrUtil.isEmpty(fieldValue), "参数(" + field.getName() + ")不能为空");
        Field tableIdField = JDBCReflectUtil.getTableIdField(dv);
        Object objValue = ReflectUtil.getObjValue(dv, tableIdField.getName());
        DV wr = JDBCReflectUtil.getDVAndSetId(this.getClass(), objValue.toString());
        wr.getTp().putAll(dv.getTp());
        return update(dv, wr);
    }

    /**
     * 根据id删除
     *
     * @param id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    default int deleteById(String id) {
        AssertUtil.isFalse(StrUtil.isEmpty(id), "参数(id)不能为空");
        return deleteByIdList(List.of(id));
    }

    /**
     * 根据id删除
     *
     * @param id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    default <T extends Number> int deleteById(T id) {
        AssertUtil.isFalse(StrUtil.isEmpty(id), "参数(id)不能为空");
        return deleteByIdList(List.of(id));
    }

    /**
     * 根据id批量删除
     *
     * @param idList
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    default int deleteByIdList(List<? extends Serializable> idList) {
        AssertUtil.isFalse(StrUtil.isEmpty(idList), "参数(idList)不能为空");
        AssertUtil.isTrue(idList.get(0) instanceof String || idList.get(0) instanceof Number, "id类型错误, 应为String或Number");
        ParameterizedType type = (ParameterizedType) ((Class<?>) this.getClass().getGenericInterfaces()[0]).getGenericInterfaces()[0];
        DV dv = ReflectUtil.invokeGenericIntf(type, 0);
        return getMapper().delete(dv.setIdInList(idList));
    }

}
